"""
参数值对象，支持属性访问和算术运算
"""
from typing import Dict, Any


class ParameterValue:
    """参数值对象，支持属性访问"""
    
    def __init__(self, param_data: Dict[str, Any]):
        self._data = param_data
        self._raw_value = param_data.get('value')
        self._param_type = param_data.get('param_type', 'string')
        self._is_list = param_data.get('is_list', False)
        
        # 根据参数类型转换值
        self._value = self._convert_value(self._raw_value)
    
    def _convert_value(self, raw_value):
        """根据参数类型转换值"""
        if raw_value is None:
            return None
        
        if self._is_list:
            # 列表参数
            if not isinstance(raw_value, list):
                return raw_value
            
            converted_list = []
            for item in raw_value:
                converted_item = self._convert_single_value(item)
                converted_list.append(converted_item)
            return converted_list
        else:
            # 单个参数
            return self._convert_single_value(raw_value)
    
    def _convert_single_value(self, value):
        """转换单个值"""
        if value is None:
            return None
        
        try:
            if self._param_type == 'integer':
                return int(float(value))  # 先转float再转int，处理"1.0"这种情况
            elif self._param_type == 'float':
                return float(value)
            elif self._param_type == 'boolean':
                if isinstance(value, bool):
                    return value
                return str(value).lower() in ['true', '1', 'yes', 'on']
            else:  # string 或其他类型
                return str(value)
        except (ValueError, TypeError):
            # 转换失败时返回原始值
            return value
    
    @property
    def value(self):
        """参数值"""
        return self._value
    
    @property
    def unit(self):
        """参数单位"""
        return self._data.get('unit')
    
    @property
    def description(self):
        """参数描述"""
        return self._data.get('description')
    
    @property
    def name(self):
        """参数中文名称"""
        return self._data.get('name')
    
    @property
    def name_en(self):
        """参数英文名称"""
        return self._data.get('name_en')
    
    @property
    def param_type(self):
        """参数类型"""
        return self._param_type
    
    @property
    def is_list(self):
        """是否为列表参数"""
        return self._is_list
    
    @property
    def is_year_related(self):
        """是否关联年份"""
        return self._data.get('is_year_related', False)
    
    @property
    def list_length(self):
        """列表长度"""
        return self._data.get('list_length')
    
    def __str__(self):
        return str(self._value)
    
    def __repr__(self):
        return f"ParameterValue(name='{self.name_en}', value={self._value}, type='{self._param_type}')"
    
    def __getitem__(self, index):
        """支持列表索引访问"""
        if not self._is_list or not isinstance(self._value, list):
            raise TypeError(f"参数 '{self.name_en}' 不是列表类型")
        return self._value[index]
    
    def __len__(self):
        """支持len()函数"""
        if not self._is_list or not isinstance(self._value, list):
            return 1
        return len(self._value)
    
    def __iter__(self):
        """支持迭代"""
        if not self._is_list or not isinstance(self._value, list):
            return iter([self._value])
        return iter(self._value)
    
    # 算术运算符重载
    def __add__(self, other):
        """加法运算"""
        if self._is_list:
            raise TypeError(f"列表参数 '{self.name_en}' 不支持算术运算")
        if self._value is None:
            return other
        return self._value + other
    
    def __radd__(self, other):
        """右加法运算"""
        return self.__add__(other)
    
    def __sub__(self, other):
        """减法运算"""
        if self._is_list:
            raise TypeError(f"列表参数 '{self.name_en}' 不支持算术运算")
        if self._value is None:
            return -other if other is not None else None
        return self._value - other
    
    def __rsub__(self, other):
        """右减法运算"""
        if self._is_list:
            raise TypeError(f"列表参数 '{self.name_en}' 不支持算术运算")
        if self._value is None:
            return other
        return other - self._value
    
    def __mul__(self, other):
        """乘法运算"""
        if self._is_list:
            raise TypeError(f"列表参数 '{self.name_en}' 不支持算术运算")
        if self._value is None:
            return 0
        return self._value * other
    
    def __rmul__(self, other):
        """右乘法运算"""
        return self.__mul__(other)
    
    def __truediv__(self, other):
        """除法运算"""
        if self._is_list:
            raise TypeError(f"列表参数 '{self.name_en}' 不支持算术运算")
        if self._value is None:
            return 0
        if other == 0:
            raise ZeroDivisionError(f"参数 '{self.name_en}' 除以零")
        return self._value / other
    
    def __rtruediv__(self, other):
        """右除法运算"""
        if self._is_list:
            raise TypeError(f"列表参数 '{self.name_en}' 不支持算术运算")
        if self._value is None:
            raise ZeroDivisionError(f"参数 '{self.name_en}' 的值为 None，无法作为除数")
        if self._value == 0:
            raise ZeroDivisionError(f"参数 '{self.name_en}' 为零，无法作为除数")
        return other / self._value
    
    def __floordiv__(self, other):
        """整除运算"""
        if self._is_list:
            raise TypeError(f"列表参数 '{self.name_en}' 不支持算术运算")
        if self._value is None:
            return 0
        if other == 0:
            raise ZeroDivisionError(f"参数 '{self.name_en}' 除以零")
        return self._value // other
    
    def __rfloordiv__(self, other):
        """右整除运算"""
        if self._is_list:
            raise TypeError(f"列表参数 '{self.name_en}' 不支持算术运算")
        if self._value is None:
            raise ZeroDivisionError(f"参数 '{self.name_en}' 的值为 None，无法作为除数")
        if self._value == 0:
            raise ZeroDivisionError(f"参数 '{self.name_en}' 为零，无法作为除数")
        return other // self._value
    
    def __mod__(self, other):
        """取模运算"""
        if self._is_list:
            raise TypeError(f"列表参数 '{self.name_en}' 不支持算术运算")
        if self._value is None:
            return 0
        if other == 0:
            raise ZeroDivisionError(f"参数 '{self.name_en}' 除以零")
        return self._value % other
    
    def __rmod__(self, other):
        """右取模运算"""
        if self._is_list:
            raise TypeError(f"列表参数 '{self.name_en}' 不支持算术运算")
        if self._value is None:
            raise ZeroDivisionError(f"参数 '{self.name_en}' 的值为 None，无法作为除数")
        if self._value == 0:
            raise ZeroDivisionError(f"参数 '{self.name_en}' 为零，无法作为除数")
        return other % self._value
    
    def __pow__(self, other):
        """幂运算"""
        if self._is_list:
            raise TypeError(f"列表参数 '{self.name_en}' 不支持算术运算")
        if self._value is None:
            return 0
        return self._value ** other
    
    def __rpow__(self, other):
        """右幂运算"""
        if self._is_list:
            raise TypeError(f"列表参数 '{self.name_en}' 不支持算术运算")
        if self._value is None:
            return 1
        return other ** self._value
    
    def __neg__(self):
        """负号运算"""
        if self._is_list:
            raise TypeError(f"列表参数 '{self.name_en}' 不支持算术运算")
        if self._value is None:
            return 0
        return -self._value
    
    def __pos__(self):
        """正号运算"""
        if self._is_list:
            raise TypeError(f"列表参数 '{self.name_en}' 不支持算术运算")
        if self._value is None:
            return 0
        return +self._value
    
    def __abs__(self):
        """绝对值运算"""
        if self._is_list:
            raise TypeError(f"列表参数 '{self.name_en}' 不支持算术运算")
        if self._value is None:
            return 0
        return abs(self._value)
    
    # 比较运算符重载
    def __eq__(self, other):
        """等于比较"""
        if self._is_list:
            return False  # 列表参数不支持比较
        return self._value == other
    
    def __ne__(self, other):
        """不等于比较"""
        return not self.__eq__(other)
    
    def __lt__(self, other):
        """小于比较"""
        if self._is_list:
            raise TypeError(f"列表参数 '{self.name_en}' 不支持比较运算")
        if self._value is None:
            return True  # None 小于任何值
        return self._value < other
    
    def __le__(self, other):
        """小于等于比较"""
        if self._is_list:
            raise TypeError(f"列表参数 '{self.name_en}' 不支持比较运算")
        if self._value is None:
            return True  # None 小于等于任何值
        return self._value <= other
    
    def __gt__(self, other):
        """大于比较"""
        if self._is_list:
            raise TypeError(f"列表参数 '{self.name_en}' 不支持比较运算")
        if self._value is None:
            return False  # None 不大于任何值
        return self._value > other
    
    def __ge__(self, other):
        """大于等于比较"""
        if self._is_list:
            raise TypeError(f"列表参数 '{self.name_en}' 不支持比较运算")
        if self._value is None:
            return False  # None 不大于等于任何值
        return self._value >= other
    
    # 数值类型转换
    def __int__(self):
        """转换为整数"""
        if self._is_list:
            raise TypeError(f"列表参数 '{self.name_en}' 无法转换为整数")
        if self._value is None:
            return 0
        return int(self._value)
    
    def __float__(self):
        """转换为浮点数"""
        if self._is_list:
            raise TypeError(f"列表参数 '{self.name_en}' 无法转换为浮点数")
        if self._value is None:
            return 0.0
        return float(self._value)
    
    def __bool__(self):
        """转换为布尔值"""
        if self._is_list:
            return len(self._value) > 0 if isinstance(self._value, list) else False
        if self._value is None:
            return False
        return bool(self._value)
    
    # 新增数值转换方法
    def __complex__(self):
        """转换为复数，供Pyomo使用"""
        if self._is_list:
            raise TypeError(f"列表参数 '{self.name_en}' 无法转换为复数")
        if self._value is None:
            return 0j
        return complex(self._value)
    
    # 让ParameterValue对象可以直接作为数值使用
    def __index__(self):
        """支持作为索引使用"""
        if self._is_list:
            raise TypeError(f"列表参数 '{self.name_en}' 无法作为索引")
        if self._value is None:
            return 0
        return int(self._value)
    
    # 支持与数值类型的比较和运算
    def __round__(self, n=None):
        """支持round()函数"""
        if self._is_list:
            raise TypeError(f"列表参数 '{self.name_en}' 无法四舍五入")
        if self._value is None:
            return 0
        return round(self._value, n)
    
    def __trunc__(self):
        """支持math.trunc()函数"""
        if self._is_list:
            raise TypeError(f"列表参数 '{self.name_en}' 无法截断")
        if self._value is None:
            return 0
        return int(self._value)
    
    def __floor__(self):
        """支持math.floor()函数"""
        if self._is_list:
            raise TypeError(f"列表参数 '{self.name_en}' 无法向下取整")
        if self._value is None:
            return 0
        import math
        return math.floor(self._value)
    
    def __ceil__(self):
        """支持math.ceil()函数"""
        if self._is_list:
            raise TypeError(f"列表参数 '{self.name_en}' 无法向上取整")
        if self._value is None:
            return 0
        import math
        return math.ceil(self._value)
    
    # 支持Pyomo约束中的数值转换
    def __pyomo_value__(self):
        """为Pyomo提供数值转换"""
        if self._is_list:
            raise TypeError(f"列表参数 '{self.name_en}' 无法转换为数值")
        if self._value is None:
            return 0.0
        return float(self._value)
    
    def __pyomo_float__(self):
        """为Pyomo提供浮点数转换"""
        return self.__pyomo_value__()
    
    def __pyomo_int__(self):
        """为Pyomo提供整数转换"""
        if self._is_list:
            raise TypeError(f"列表参数 '{self.name_en}' 无法转换为整数")
        if self._value is None:
            return 0
        return int(self._value)
    
    # 让ParameterValue在需要时自动转换为数值
    def __call__(self):
        """当对象被调用时返回数值"""
        return self.__pyomo_value__()
    
    def __getattr__(self, name):
        """当访问不存在的属性时，尝试返回数值"""
        if name in ['value', 'val', 'numeric']:
            return self.__pyomo_value__()
        raise AttributeError(f"'{self.__class__.__name__}' object has no attribute '{name}'")
    
    def __hash__(self):
        """支持哈希操作，让对象可以作为字典的键"""
        if self._is_list:
            return hash(tuple(self._value) if isinstance(self._value, list) else ())
        if self._value is None:
            return hash(0)
        return hash(self._value)

